﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Media;
using System.Windows.Documents;
using System.Windows.Controls;
using System.Windows.Data;
using System.Threading;
using System.Windows.Media.Animation;
using System.Text.RegularExpressions;
using System.Windows.Shapes;
using System.Windows.Media.Effects;
using System.Diagnostics;
using WGM_Client_Net35.Properties;
namespace WGM_Client_Net35
{
    public partial class TabListItem : INotifyPropertyChanged
    {
        public string MyFontColour { get; set; }
        public FontFamily MyFontFamily { get; set; }
        public FontWeight MyFontWeight { get; set; }
        public FontStyle MyFontStyle { get; set; }

        public double MyFontSize { get; set; }
        public string TabHeaderToolTip { get; set; }
        private WGM_Service.UserOptions _myOnlineOptions;
        public bool IsUserOnline { get; set; }
        private double _tabOpacity;
        public double TabOpacity 
        {
            get { return _tabOpacity; }
            set { _tabOpacity = value; OnPropertyChanged("TabOpacity"); }
        }
        private string _tabHeaderText;
        public string TabHeaderText 
        {
            get { return _tabHeaderText; }
            set { _tabHeaderText = value; OnPropertyChanged("TabHeaderText"); }
        }
        public string IncomingListName { get; set; }
        public string OutgoingTBName { get; set; }
        private string _tabHeaderColour;
        public FlowDocument OutgoingText { get; set; }
        public string TabHeaderColour 
        {
            get { return _tabHeaderColour; }
            set { _tabHeaderColour = value; OnPropertyChanged("TabHeaderColour"); } 
        }
        private bool _isTabSelected = false;
        public Visibility CloseButtonVisibility { get; set; }
        public bool IsTabSelected 
        {
            get { return _isTabSelected; }
            set 
            { 
                _isTabSelected = value; 
                OnPropertyChanged("IsTabSelected");
                if (value == true) 
                    Owner.SetSelectedTab(this);
            } 
        }
        public FlowDocument MessageDoc { get; set; }
        private Paragraph _para = new Paragraph();
        public bool FlashTab { get; set; }
        public MainWindow Owner { get; private set; }
        public void SetTabData(WGM_Service.UserOptions uo, bool isOnline)
        {
            IsUserOnline = isOnline;
            if (IsUserOnline == false)
            {
                TabHeaderText = HelperFunctions.GetContactTitle(uo) + " *OFFLINE*";
                TabOpacity = 0.5;
                TabHeaderColour = Colors.DarkGray.ToString();
            }
            else
            {
                TabHeaderText = HelperFunctions.GetContactTitle(uo);
                TabOpacity = 1;
                TabHeaderColour = HelperFunctions.GetNewColour(uo).ToString() ;
            }
            TabHeaderToolTip = HelperFunctions.GetCLToolTip(uo) + (isOnline?"":" *OFFLINE*");
            OnPropertyChanged("TabHeaderToolTip");
        }
        public TabListItem(MainWindow owner, WGM_Service.UserOptions myOnlineOptions, string tabHeaderText, string incomingListName, string outgoingTBName, string tabHeaderColour, bool isOnline)
        {

            Owner = owner;
            SetMyOnlineOptions(myOnlineOptions);
            IsUserOnline = isOnline;
            _tabOpacity = 1.0;
            _tabHeaderText = tabHeaderText;
            IncomingListName = incomingListName;
            OutgoingTBName = outgoingTBName;
            OutgoingText = new FlowDocument();

            _tabHeaderColour = tabHeaderColour;
            CloseButtonVisibility = Visibility.Visible;
            FlashTab = false;
            MessageDoc = new FlowDocument();
            OutgoingText.LineHeight = 1;
            MessageDoc.LineHeight = 1;
            MessageDoc.Blocks.Add(_para);
            TabHeaderToolTip = OutgoingTBName;
            
        }
        public void SetMyOnlineOptions(WGM_Service.UserOptions myOnlineOptions)
        {
            _myOnlineOptions = myOnlineOptions;
            MyFontFamily = new FontFamily( myOnlineOptions.UserFontFace);
            MyFontSize = myOnlineOptions.FontSize;
            if (myOnlineOptions.IsFontItalics)
                MyFontStyle = FontStyles.Italic;
            else
                MyFontStyle = FontStyles.Normal;
            if (myOnlineOptions.IsFontBold)
                MyFontWeight = FontWeights.Bold;
            else
                MyFontWeight = FontWeights.Regular;



            MyFontColour = HelperFunctions.GetNewColour(myOnlineOptions).ToString();
            OnPropertyChanged("MyFontFamily");
            OnPropertyChanged("MyFontSize");
            OnPropertyChanged("MyFontStyle");
            OnPropertyChanged("MyFontWeight");
            OnPropertyChanged("MyFontColour");
            OnPropertyChanged("MyFontDecorations");
        }
        public void FlashTabItem()
        {
            FlashTab = true;
            OnPropertyChanged("FlashTab");
            FlashTab = false;
            OnPropertyChanged("FlashTab");

        }
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        public void AddMessage(LocalMessageItem message, ConnectionHandlerObject cho)
        {
            WGM_Service.UserOptions senderOptions = cho.GetUserOptions(message.Sender);
            if (senderOptions == null)
            {
                Run introRun = new Run("<"+DateTime.Now.ToString()+"> System Error:\r\n");
                introRun.Foreground = new SolidColorBrush(Colors.Red);
                introRun.FontFamily = Properties.Settings.Default.SystemFontFamily;
                introRun.FontSize = Properties.Settings.Default.SystemFontSize;

                if (Settings.Default.IsSystemFontBold)
                    introRun.FontWeight = FontWeights.Bold;
                if (Settings.Default.IsSystemFontItalics)
                    introRun.FontStyle = FontStyles.Italic;
                if (Settings.Default.IsSystemFontUnderlined)
                    introRun.TextDecorations = TextDecorations.Underline;

                _para.Inlines.Add(introRun);

                Run messageRun = new Run(message.MessageText + "\r\n");


                messageRun.FontFamily = new FontFamily( _myOnlineOptions.UserFontFace);
                messageRun.Foreground = new SolidColorBrush( HelperFunctions.GetNewColour(_myOnlineOptions));
                messageRun.FontSize = _myOnlineOptions.FontSize;
                if (_myOnlineOptions.IsFontBold)
                    messageRun.FontWeight = FontWeights.Bold;
                if (_myOnlineOptions.IsFontItalics)
                    messageRun.FontStyle = FontStyles.Italic;
                if (_myOnlineOptions.IsFontUnderlined)
                    messageRun.TextDecorations = TextDecorations.Underline;

                _para.Inlines.Add(messageRun);
            }
            else
            {

                SolidColorBrush introBrush = new SolidColorBrush(Color.FromRgb((byte)Properties.Settings.Default.SystemFontColorR,
                                                                             (byte)Properties.Settings.Default.SystemFontColorG,
                                                                             (byte)Properties.Settings.Default.SystemFontColorB));
                Color overrideColour = Color.FromRgb((byte)Settings.Default.OverrideIncomingFontColourR,
                                                     (byte)Settings.Default.OverrideIncomingFontColourG,
                                                     (byte)Settings.Default.OverrideIncomingFontColourB);
                if (Settings.Default.OverrideIncomingFonts && senderOptions.UserName.ToLower().Trim() != cho.CurrentUserName.ToLower().Trim())
                    message.MessageColour = overrideColour;
                SolidColorBrush messageBrush = new SolidColorBrush(message.MessageColour);
                


                string runIntro = "";
                if (Properties.Settings.Default.DisplayDateTimeStamp == true)
                    runIntro += "<" + message.MessageDate.ToString() + "> ";
                if(Properties.Settings.Default.DisplayMessageTimeDelay ==true)
                {
                    DateTime now = DateTime.Now;
                    DateTime serverTime = now + cho.ServerTimeOffset;
                    TimeSpan delay = message.MessageDate - serverTime;
                    runIntro += " (" + (int)(delay.TotalMilliseconds) + "ms) ";
                }
                Run introRun = new Run(runIntro+ HelperFunctions.GetIntroString(senderOptions)+" says:\r\n");
                introRun.FontFamily = Properties.Settings.Default.SystemFontFamily;
                introRun.FontSize = Properties.Settings.Default.SystemFontSize;

                if (Settings.Default.IsSystemFontBold)
                    introRun.FontWeight = FontWeights.Bold;
                if (Settings.Default.IsSystemFontItalics)
                    introRun.FontStyle = FontStyles.Italic;
                if (Settings.Default.IsSystemFontUnderlined)
                    introRun.TextDecorations = TextDecorations.Underline;



                introRun.Foreground = introBrush;


                _para.Inlines.Add(introRun);
                
                Run messageRun = new Run(message.MessageText+"\r\n");

                messageRun.FontFamily = message.SenderFontFamily == null ? new FontFamily("Arial") : message.SenderFontFamily;
                messageRun.FontSize = message.SenderFontSize;
                if (senderOptions.IsFontBold)
                    messageRun.FontWeight = FontWeights.Bold;
                if (senderOptions.IsFontItalics)
                    messageRun.FontStyle = FontStyles.Italic;
                if(senderOptions.IsFontUnderlined)
                    messageRun.TextDecorations = TextDecorations.Underline;

                if (Settings.Default.OverrideIncomingFonts && senderOptions.UserName.ToLower().Trim() != cho.CurrentUserName.ToLower().Trim() )
                {
                    messageRun.FontFamily = Settings.Default.OverrideIncomingFontFamily;
                    messageRun.FontSize = Settings.Default.OverrideIncomingFontSize;
                    if (Settings.Default.IsOverrideFontBold)
                        messageRun.FontWeight = FontWeights.Bold;
                    if (Settings.Default.IsOverrideFontItalics)
                        messageRun.FontStyle = FontStyles.Italic;
                    if (Settings.Default.IsOverrideFontUnderlined)
                        messageRun.TextDecorations = TextDecorations.Underline;
                }

                messageRun.Foreground = messageBrush;


                Regex linkMatch = new Regex("(?:^|[\\s\\[\\]\\}\\{\\(\\)\\\'\\\"<>])((?:(?:https?|gopher|ftp|file|irc):\\/\\/|www\\.)[a-zA-Z0-9\\.\\-=;&%\\?]+(?:\\/?[a-zA-Z0-9\\.\\-=;,~`*_#$+&%\\?]*)*)"); 
                MatchCollection matches = linkMatch.Matches(messageRun.Text);
                _para.Inlines.Add(messageRun);
                if (matches.Count > 0)
                {
                    Run linksHeader = new Run("Message contains the following links:\r\n");
                    linksHeader.FontFamily = message.SystemFontFamily;
                    linksHeader.Foreground = introBrush;
                    _para.Inlines.Add(linksHeader );
                    foreach (Match match in matches)
                    {
                        Hyperlink hp = new Hyperlink(new Run(match.Value.Trim()));
                        hp.Foreground = messageBrush;
                        hp.Click += new RoutedEventHandler(hyperlink_Click);
                        hp.Tag = match.Value.Trim();
                        _para.Inlines.Add(hp);
                        _para.Inlines.Add(new Run("\r\n"));
                    }
                }

            } 
        }

        void hyperlink_Click(object sender, RoutedEventArgs e)
        {
            Hyperlink link = sender as Hyperlink;
            try
            {
                Process.Start(link.Tag.ToString());
            }
            catch { }
        }

        public event PropertyChangedEventHandler PropertyChanged;

    }
    public partial class LocalMessageItem
    {
        public DateTime MessageDate { get; set; }
        public string MessageText { get; set; }
        public string Sender { get; set; }
        public bool DateVisible { get; set; }
        public string SystemColour { get; set; }
        public Color MessageColour { get; set; }
        public FontFamily SystemFontFamily { get; set; }
        public FontFamily SenderFontFamily { get; set; }
        public FontWeight SenderFontWeight { get; set; }
        public FontStyle SenderFontStyle { get; set; }
        public double SenderFontSize { get; set; }
        public LocalMessageItem(DateTime date, string messageText,Color messageColour, string sender, bool datevisible, string systemColour)
        {
            SenderFontStyle = FontStyles.Normal;
            SenderFontWeight = FontWeights.Normal;
            MessageDate = date;
            MessageText = messageText;
            Sender = sender;
            DateVisible = datevisible;
            SystemColour = systemColour;
            SystemFontFamily = new FontFamily("Arial");
            MessageColour = messageColour;
            SenderFontSize = 10;
        }
    }
    public partial class ContactListItem : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public bool IsContactOnline { get; set; }
        public string UserName { get; set; }
        public System.Drawing.Image DisplayImage { get; set; }
        private string _displayName;
        private string _displayStatus;
        private string _displayTooltip;
        private string _displayNameColour = Colors.DarkGray.ToString();
        private string _displayHighlightColour = Colors.DarkGray.ToString();
        public string DisplayHighlightColour 
        {
            get { return _displayHighlightColour; }
            set
            {
                _displayHighlightColour = value;
                OnPropertyChanged("DisplayHighlightColour");
            }
        }
        public Visibility DisplayStatusVisiblity { get; set; }
        public object ContactData { get; set; }
        public string DisplayNameColour 
        {
            get { return _displayNameColour; } 
            set
            {
                _displayNameColour = value;
                OnPropertyChanged("DisplayNameColour");
            } 
        }
        public bool FlashContact { get; set; }
        public string DisplayName 
        {
            get { return _displayName; }
            set 
            { 
                _displayName = value;
                OnPropertyChanged("DisplayName");
            } 
        }
        public string DisplayStatus 
        {
            get { return _displayStatus; }
            set
            {
                _displayStatus = value;
                OnPropertyChanged("DisplayStatus");
                if (value == null || value.Trim() == "")
                    DisplayStatusVisiblity = Visibility.Collapsed;
                else
                    DisplayStatusVisiblity = Visibility.Visible;
            } 
        }
        public string DisplayTooltip 
        {
            get { return _displayTooltip; }
            set
            {
                _displayTooltip = value;
                OnPropertyChanged("DisplayTooltip");
            } 
        }
        public void SetContactData(WGM_Service.UserOptions uo)
        {
            DisplayName = uo.DisplayName;
            DisplayStatus = uo.UserStatus;
            DisplayTooltip = HelperFunctions.GetCLToolTip(uo);
            
        }
        public ContactListItem(string userName, string displayName, string displayStatus, string displayToolTip, object contactData)
        {
            IsContactOnline = false;
            _displayName = displayName;
            _displayStatus = displayStatus;
            _displayTooltip = displayToolTip;
            ContactData = contactData;
            UserName = userName;
            DisplayStatusVisiblity = Visibility.Visible;
            if (displayStatus == null || displayStatus.Trim() == "")
                DisplayStatusVisiblity = Visibility.Collapsed;
            
            FlashContact = false;
        }
        public void SetContactOnline(bool isOnline)
        {
            if (IsContactOnline != isOnline)
            {
                if (isOnline == true )
                {
                    FlashContactItem();                    
                    DisplayNameColour = Colors.LightGreen.ToString();
                    DisplayHighlightColour = DisplayNameColour;
                }
                if (isOnline == false)
                {
                    DisplayNameColour = Colors.DarkGray.ToString();
                    DisplayHighlightColour = DisplayNameColour;
                }
                IsContactOnline = isOnline;
            }
        }
        public void FlashContactItem()
        {
            if (Properties.Settings.Default.IsFancyEffectsEnabled)
            {
                FlashContact = true;
                OnPropertyChanged("FlashContact");
                FlashContact = false;
                OnPropertyChanged("FlashContact");
            }
        }

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

    }

    public interface IWGM_Client
    {

    }
}
